package connect4client.commands;


import messages.Message;
import connect4client.core.*;


/**
 * Command pattern.
 * 
 * Each Command sub-type will handle, though the execute() method, a specific
 * type of Message.
 */
public abstract class Command {

	public Command(Message message) {
		this.message = message;	
	}

	/**
	 * Create a Command object to handle the message received.
	 * Uses reflection to create the commands by name. I.e, for each
	 * Message type there is a correspondent Command type (WallMessage <-> WallCommand).
	 * 
	 * @param message Message to handle
	 * @return The command created.
	 */
	public static Command parse(Message message, Controller controller) {
		String messageClassName = message.getClass().getSimpleName();
		String commandClassName = messageClassName
		.substring(0, messageClassName.length() - "Message".length()) + "Command";
		Command cmd = null;

		try {			
			cmd = (Command) Class.forName("connect4client.commands." + commandClassName)
			.getConstructors()[0].newInstance(message); // Magic
			
			cmd.controller = controller;
			cmd.guiMediator = controller.getGUIMediator();
		} catch (Exception e) {
			System.err.println("Received an invalid message from the server: " + message);
		} 

		return cmd;
	}


	/**
	 * Handles each Message appropriately.
	 * Each derived class will implement this method in a specific way.
	 */
	public abstract void execute();



	protected Controller controller;	// ClientApplication controller
	protected GUIMediator guiMediator;
	protected Message message; 			// The message this command will handle
}

